先建個表方便理解
mysql> create table account (
-> id int not null auto_increment comment '自動增加id',
-> name varchar(100) comment '客戶名稱',
-> balance int comment '餘額',
-> primary key (id)
-> ) engine=InnoDB charset=utf8;
Query OK, 0 rows affected, 1 warning (0.45 sec)
mysql> insert account (name, balance) values ('小蛙', 1000000), ('你', 0);
Query OK, 2 rows affected (0.15 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from account;
+----+--------+---------+
| id | name | balance |
+----+--------+---------+
| 1 | 小蛙 | 1000000 |
| 2 | 你 | 0 |
+----+--------+---------+
2 rows in set (0.01 sec)
假設你要跟小蛙借10塊錢
執行的敘述可能是這樣
update account set balance = balance - 10 where id = 1;
update account set balance = balance + 10 where id = 2;
先從小蛙的帳戶扣10塊,再轉到你的帳戶。
但如果扣了錢之後,系統crash,導致你沒收到錢,那雙方不就傻爆眼了@o@
因此可發現一個簡單的現實交易行為,要在資料庫實現沒有那麼單純的
這邊就要提到交易機制的四大特性,來確保交易機制沒有問題!
原子性
現實世界轉帳是一個不可分割的操作,也就是要嘛轉帳成功,要嘛失敗,沒有轉一半的情況
也就是說要嘛全做,要嘛全不做,這個規則就稱為原子性。
隔離性
在現實世界中,從小蛙的帳戶扣10塊,再轉到你的帳戶,這兩個狀態是不會互相影響的。
但在資料庫裡面要實現卻沒有這麼單純,因為執行操作的過程有可能是異步的,表示有可能不會確定從小蛙的帳戶扣10塊之後,再轉到你的帳戶,因此多了一個機制確保交易變更狀態彼此不會互相影響,這個規則就稱為隔離性。
一致性
顧名思義就是致力於維持資料庫內的資料一致性。
持久性
表示所有保存在磁碟的變更資料,無論之後發生了什麼事都應該永久保存。
需要保證原子性(Atomicity)、隔離性(Isolation)、一致性(Consistency)、持久性(Durability)的或多個資料庫操作就是交易。而將這四個單字的字首取出來就是A、I、C、D,稍微變化一下順序形成一個完整的單字ACID(酸的意思),以後提到ACID就知道是這四個規則的意思。
交易在執行的過程中,有以下狀態:
活動的
交易對應的資料庫操作正在執行中
部分提交的
當最後一個操作執行完成,最新的資料還在記憶體中,並沒有刷新到磁碟,這個狀態就是部分提交的
失敗的
遇到某些錯誤
中止的
當資料庫操作失敗後,資料會回覆操作(回到資料變更前一開始的狀態),這時就會變成中止的狀態
提交的
當部分操作的資料刷新回磁碟即為提交。